package com.kizuki.thread;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class TestReentrantReadWriteLock {

    @Test
    public void test(){
        final int num = 5;
        MyCache myCache = new MyCache();

        for (int i = 0; i < num; i++) {
            final int temp = i;
            new Thread(()->{
                myCache.write(temp, String.valueOf(temp));
            }, String.valueOf(i)).start();
        }

        for (int i = 0; i < num; i++) {
            final int temp = i;
            new Thread(()->{
                myCache.read(temp);
            }, String.valueOf(i)).start();
        }

    }

}

class MyCache {
    private volatile Map<Integer, String> map = new HashMap<>();
    // 更细颗粒度的锁
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void write(Integer k, String v) {
        lock.writeLock().lock();
        try {
            // 保证写入时只有一个线程
            System.out.println(Thread.currentThread().getName() + "写入准备");
            map.put(k, v);
            System.out.println(Thread.currentThread().getName() + "写入完毕");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }

    public void read(Integer k) {
        lock.readLock().lock();
        try {
            // 同时可以有多个线程读取
            System.out.println(Thread.currentThread().getName() + "读取准备");
            map.get(k);
            System.out.println(Thread.currentThread().getName() + "读取完毕");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
    }

}
